﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using CeVIO.SFE.Song.Models;

// ReSharper disable InconsistentNaming

namespace VOICeVIO.Hybrid.Services
{
    public class SvssService
    {
        private readonly string _wavPath = "waves";
        private readonly string _voiceDicPath = @"Configuration\Dictionary\Song\";

        public Stream GetWave(Guid guid)
        {
            var path = Path.Combine(_wavPath, guid.ToString("N") + ".wav");
            if (!File.Exists(path))
            {
                return null;
            }

            return File.Open(path, FileMode.Open);
        }

        public async Task<(bool result, string info)> Synth(Singer cv, string xmlPath, Guid guid, double volume = 6.0)
        {
            string info = "";
            if (!Directory.Exists(_wavPath))
            {
                Directory.CreateDirectory(_wavPath);
            }
            var voiceModelPath = @"Configuration\VocalSource\Song\Yoko\f001_svss.tsvoice";
            switch (cv)
            {
                case Singer.Yoko:
                    voiceModelPath = @"Configuration\VocalSource\Song\Yoko\f001_svss.tsvoice";
                    break;
                case Singer.Yokun:
                    voiceModelPath = @"Configuration\VocalSource\Song\Yoko\m001_svss.tsvoice";
                    break;
                case Singer.TsudumiCool:
                    voiceModelPath = @"Configuration\VocalSource\Song\Official-B\f802_cool_svss.tsvoice";
                    break;
                case Singer.TsudumiBashful:
                    voiceModelPath = @"Configuration\VocalSource\Song\Official-B\f802_bashful_svss.tsvoice";
                    break;
                case Singer.IA:
                    break;
                default:
                    break;
            }

            bool result = false;
            await Task.Run(() =>
            {
                try
                {
                    var singer = new CeVIO.SFE.Song.Singer();
                    singer.Init("");
                    singer.InitializeVoice(voiceModelPath, _voiceDicPath, 0);
                    var s = new Score(guid, false);
                    singer.ScoreDictionary.Add(s.TrackId, s);
                    singer.ChangeVoice(s.TrackId, voiceModelPath, _voiceDicPath, 0, 0.55, 0.55, 0.5, 0.6);
                    if (!singer.LoadFromFile(s, xmlPath))
                    {
                        result = false;
                        info = "Project file is invalid.";
                    }
                    if (s.Duration.TotalMinutes > 5)
                    {
                        result = false;
                        info = "The song is too long.";
                    }
                    s.UpdateTotalLength();
                    result = singer.Save(s.TrackId, volume, Path.Combine(_wavPath, guid.ToString("N") + ".wav"));
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    result = false;
                    info = "Critical Error.";
                }
            });

            return (result, info);
        }
    }
}

